package com.gardenguell.salad.ui.view;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.gardenguell.salad.R;
import com.gardenguell.salad.data.model.EnviromentParams;
import com.gardenguell.salad.ui.view.graph.Line;
import com.gardenguell.salad.ui.view.graph.LineGraph;
import com.gardenguell.salad.ui.view.graph.LinePoint;
import com.gardenguell.salad.util.ResUtil;
import org.w3c.dom.Text;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by absurd on 16/2/24.
 */
public class DataGraph extends LinearLayout implements View.OnClickListener{

    private static final String LINE_COLOR = "#61a983";
    private static final int[][] SCOPE = {{0, 35}, {0, 100}, {0, 5000}, {0, 3000}};
    private static final String[] SYMBOL = {"℃", "%", "lux", "μS/cm"};

    private LinearLayout mXUnitView;
    private LinearLayout mYUnitView;
    private LineGraph mLineGraph;
    private TextView mRealTimeBtn;
    private TextView mOneDayBtn;
    private TextView mOneWeekBtn;
    private TextView mOneMonthBtn;

    private TextView mTemperature;
    private TextView mIllumination;
    private TextView mHumidity;
    private TextView mNutrient;


    private int mXMinUnit;
    private int mXMaxUnit;
    private int mYMinUnit;
    private int mYMaxUnit;

    public List<EnviromentParams> realTimeData = new ArrayList<>(10);
    public List<EnviromentParams> oneDayData = new ArrayList<>(10);
    public List<EnviromentParams> oneWeekData = new ArrayList<>(10);
    public List<EnviromentParams> oneMonthData = new ArrayList<>(10);

    /**
     * 0 , 1, 2, 3
     */
    public int mCurrentParam = 0;
    /**
     * 0, 1, 2, 3
     */
    private int mCurrentStat = 0;

    public DataGraph(Context context) {
        this(context, null);
    }

    public DataGraph(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DataGraph(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        LayoutInflater.from(context).inflate(R.layout.view_data_graph, this, true);
        mXUnitView = (LinearLayout)findViewById(R.id.x_unit);
        mYUnitView = (LinearLayout)findViewById(R.id.y_unit);
        mLineGraph = (LineGraph)findViewById(R.id.line_graph);

        mRealTimeBtn = (TextView)findViewById(R.id.btn_realtime);
        mOneDayBtn = (TextView)findViewById(R.id.btn_oneday);
        mOneWeekBtn = (TextView)findViewById(R.id.btn_oneweek);
        mOneMonthBtn = (TextView)findViewById(R.id.btn_onemonth);
        mTemperature = (TextView)findViewById(R.id.tv_temperature);
        mIllumination = (TextView)findViewById(R.id.tv_illumination);
        mHumidity = (TextView)findViewById(R.id.tv_humidity);
        mNutrient = (TextView)findViewById(R.id.tv_nutrient);

        mRealTimeBtn.setOnClickListener(this);
        mOneDayBtn.setOnClickListener(this);
        mOneWeekBtn.setOnClickListener(this);
        mOneMonthBtn.setOnClickListener(this);
        findViewById(R.id.btn_temperature).setOnClickListener(this);
        findViewById(R.id.btn_illumination).setOnClickListener(this);
        findViewById(R.id.btn_humidity).setOnClickListener(this);
        findViewById(R.id.btn_nutrient).setOnClickListener(this);

        initData();

        selectOneBtn(R.id.btn_realtime);

        inflateDataGraph();
    }

    private void setXUnit(int min, int max, String unitName, int num){
        mXUnitView.removeAllViews();
        mXMinUnit = min;
        mXMaxUnit = max;
        for(int i = 0; i < num; i++) {
            int unit = min + i * (max - min + 1) / num;
            TextView textView = new TextView(this.getContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
            textView.setLayoutParams(params);
            textView.setGravity(Gravity.CENTER);
            textView.setText(unit + unitName);
            mXUnitView.addView(textView);
        }
    }

    private void setXUnit(int min, int max, String unitName){
        setXUnit(min, max, unitName, 10);
    }

    private void setYUnit(int min, int max, String unitName, int num){
        mYUnitView.removeAllViews();
        mYMinUnit = min;
        mYMaxUnit = max;
        for(int i = num; i >= 0; i--) {
            int unit = min + i * (max - min) / num;
            TextView textView = new TextView(this.getContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 0, 1);
            textView.setLayoutParams(params);
            textView.setGravity(Gravity.CENTER);
            textView.setText(unit + unitName);
            mYUnitView.addView(textView);
        }
    }
    private void setYUnit(int min, int max, String unitName){
        setYUnit(min, max, unitName, 5);
    }

    public void inflateDataGraph(){
        int min = SCOPE[mCurrentParam][0];
        int max = SCOPE[mCurrentParam][1];
        mLineGraph.removeAllLines();
        Line l = new Line();
        l.setStrokeWidth(2);
        List<Float> data = getParamsListFromEnvList();
        for(int i = 0; i < data.size(); i++){
            LinePoint p = new LinePoint();
            p.setColor(LINE_COLOR);
            p.setX(i);
            p.setY(data.get(i));
            l.addPoint(p);
        }
        if(l.getSize() != 0) {
            mLineGraph.addLine(l);
        }
        mLineGraph.setRangeY(min, max);
        mLineGraph.setLineToFill(0);
        l.setColor(Color.parseColor(LINE_COLOR));
        mLineGraph.invalidate();

        setXUnit(1, 10, "");
        setYUnit(min, max, SYMBOL[mCurrentParam]);
    }

    private List<Float> getParamsListFromEnvList(){
        List<EnviromentParams> data;
        List<Float> res = new ArrayList<>();
        data = getStatParamList(mCurrentStat);
        for(int i = 0; i < data.size(); i++){
            if(mCurrentParam == 0){
                res.add(data.get(i).getTemperature());
            }else if(mCurrentParam == 1){
                res.add(data.get(i).getHumidity());
            }else if(mCurrentParam == 2){
                res.add(data.get(i).getIllumination());
            }else{
                res.add(data.get(i).getNutrient());
            }
        }
        return res;
    }

    private List<EnviromentParams> getStatParamList(int statId){
        List<EnviromentParams> res;
        if(statId == 0){
            res = realTimeData;
        }else if(statId == 1){
            res = oneDayData;
        }else if(statId == 2){
            res = oneWeekData;
        }else{
            res = oneMonthData;
        }
        return res;
    }


    public void bindData(int statId, EnviromentParams param){
        List<EnviromentParams> data = getStatParamList(statId);
        moveData(param, data);
        DecimalFormat decimalFormat = new DecimalFormat(".0");
        mTemperature.setText(decimalFormat.format(param.getTemperature()));
        mIllumination.setText(decimalFormat.format(param.getIllumination()));
        mHumidity.setText(decimalFormat.format(param.getHumidity()));
        mNutrient.setText(decimalFormat.format(param.getNutrient()));
        inflateDataGraph();
    }

    private void moveData(EnviromentParams param, List<EnviromentParams> data){
        for(int i = 9; i >= 1; i--){
            data.set(i, data.get(i-1));
        }
        data.set(0, param);
    }


    public void bindData(int statId, List<EnviromentParams> paramsList){

    }

    private void initData(){
        for(int i = 0; i < 10; i++){
            realTimeData.add(new EnviromentParams(SCOPE[0][0], SCOPE[1][0], SCOPE[2][0], SCOPE[3][0]));
            oneDayData.add(new EnviromentParams(SCOPE[0][0], SCOPE[1][0], SCOPE[2][0], SCOPE[3][0]));
            oneWeekData.add(new EnviromentParams(SCOPE[0][0], SCOPE[1][0], SCOPE[2][0], SCOPE[3][0]));
            oneMonthData.add(new EnviromentParams(SCOPE[0][0], SCOPE[1][0], SCOPE[2][0], SCOPE[3][0]));
        }
    }


    private void selectOneBtn(int btnId){
        mRealTimeBtn.setBackgroundColor(ResUtil.getColor(R.color.main_background));
        mRealTimeBtn.setTextColor(ResUtil.getColor(android.R.color.darker_gray));
        mOneDayBtn.setBackgroundColor(ResUtil.getColor(R.color.main_background));
        mOneDayBtn.setTextColor(ResUtil.getColor(android.R.color.darker_gray));
        mOneWeekBtn.setBackgroundColor(ResUtil.getColor(R.color.main_background));
        mOneWeekBtn.setTextColor(ResUtil.getColor(android.R.color.darker_gray));
        mOneMonthBtn.setBackgroundColor(ResUtil.getColor(R.color.main_background));
        mOneMonthBtn.setTextColor(ResUtil.getColor(android.R.color.darker_gray));
        findViewById(btnId).setBackgroundColor(ResUtil.getColor(R.color.theme_color));
        ((TextView)findViewById(btnId)).setTextColor(ResUtil.getColor(android.R.color.white));
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.btn_realtime:
                selectOneBtn(R.id.btn_realtime);
                mCurrentStat = 0;
                inflateDataGraph();
                break;
            case R.id.btn_oneday:
                selectOneBtn(R.id.btn_oneday);
                mCurrentStat = 1;
                inflateDataGraph();
                break;
            case R.id.btn_oneweek:
                selectOneBtn(R.id.btn_oneweek);
                mCurrentStat = 2;
                inflateDataGraph();
                break;
            case R.id.btn_onemonth:
                selectOneBtn(R.id.btn_onemonth);
                mCurrentStat = 3;
                inflateDataGraph();
                break;
            case R.id.btn_temperature:
                ((ImageView)findViewById(R.id.btn_temperature)).setImageResource(R.mipmap.ic_temperature_pressed);
                ((ImageView)findViewById(R.id.btn_illumination)).setImageResource(R.mipmap.ic_illumination);
                ((ImageView)findViewById(R.id.btn_humidity)).setImageResource(R.mipmap.ic_humidity);
                ((ImageView)findViewById(R.id.btn_nutrient)).setImageResource(R.mipmap.ic_nutrient);
                mCurrentParam = 0;
                inflateDataGraph();
                break;
            case R.id.btn_humidity:
                ((ImageView)findViewById(R.id.btn_temperature)).setImageResource(R.mipmap.ic_temperature);
                ((ImageView)findViewById(R.id.btn_illumination)).setImageResource(R.mipmap.ic_illumination);
                ((ImageView)findViewById(R.id.btn_humidity)).setImageResource(R.mipmap.ic_humidity_pressed);
                ((ImageView)findViewById(R.id.btn_nutrient)).setImageResource(R.mipmap.ic_nutrient);
                mCurrentParam = 1;
                inflateDataGraph();
                break;
            case R.id.btn_illumination:
                ((ImageView)findViewById(R.id.btn_temperature)).setImageResource(R.mipmap.ic_temperature);
                ((ImageView)findViewById(R.id.btn_illumination)).setImageResource(R.mipmap.ic_illumination_pressed);
                ((ImageView)findViewById(R.id.btn_humidity)).setImageResource(R.mipmap.ic_humidity);
                ((ImageView)findViewById(R.id.btn_nutrient)).setImageResource(R.mipmap.ic_nutrient);
                mCurrentParam = 2;
                inflateDataGraph();
                break;
            case R.id.btn_nutrient:
                ((ImageView)findViewById(R.id.btn_temperature)).setImageResource(R.mipmap.ic_temperature);
                ((ImageView)findViewById(R.id.btn_illumination)).setImageResource(R.mipmap.ic_illumination);
                ((ImageView)findViewById(R.id.btn_humidity)).setImageResource(R.mipmap.ic_humidity);
                ((ImageView)findViewById(R.id.btn_nutrient)).setImageResource(R.mipmap.ic_nutrient_pressed);
                mCurrentParam = 3;
                inflateDataGraph();
                break;
            default:
                break;
        }
    }

}
